#include "lwip/sockets.h"
#include "type.h"
#include "NetSysCall.h"
#include "io.h"
#include "task.h"

const NetOper netOper={
	.SysAccept=lwip_accept,
	.SysBind=lwip_bind,
	.SysShutdown=lwip_shutdown,
	.SysGetpeername=lwip_getpeername,
	.SysGetsockname=lwip_getsockname,
	.SysSetsockopt=lwip_setsockopt,
	.SysGetsockopt=lwip_getsockopt,
	.SysClose=lwip_close,
	.SysConnect=lwip_connect,
	.SysListen=lwip_listen,
	.SysRecv=lwip_recv,
	.SysRecvmsg=lwip_recvmsg,
	.SysRecvfrom=lwip_recvfrom,
	.SysSend=lwip_send,
	.SysSendmsg=lwip_sendmsg,
	.SysSendto=lwip_sendto,
	.SysSocket=lwip_socket,
	.SysSelect=lwip_select,
	.SysPoll=lwip_poll,
	.SysIoctl=lwip_ioctl,
	.SysInetNtop=lwip_inet_ntop,
	.SysInetPton=lwip_inet_pton
};
ssize_t SysRecv(int s, void *mem, size_t len, int flags){
	PFile pFiles=GetTaskInfo(-1)->fileList;
	return lwip_recv(pFiles[s].lwipSock, mem, len, flags);
}
int SysSend(int s, const void *data, size_t size, int flags){
	PFile pFiles=GetTaskInfo(-1)->fileList;
	return lwip_send(pFiles[s].lwipSock, data,size,flags);
}
int SysAccept(int s, struct sockaddr *addr, socklen_t *addrlen){
	PFile pFiles=GetTaskInfo(-1)->fileList;
	int newSock = lwip_accept(pFiles[s].lwipSock,addr,addrlen);
	for(uint32_t i=0;i<FILE_MAX_NUM;i++){
		if(pFiles[i].isUsed==0){
			pFiles[i].lwipSock=newSock;
			pFiles[i].pNetOper=&netOper;
			pFiles[i].isUsed=TRUE;
			pFiles[i].fileType=1;
			return i;
		}
	}
	return -1;
}
int SysBind(int s, const struct sockaddr *name, socklen_t namelen){
	PFile pFiles=GetTaskInfo(-1)->fileList;
	return lwip_bind(pFiles[s].lwipSock,name,namelen);
}
int SysShutdown(int s, int how){
	PFile pFiles=GetTaskInfo(-1)->fileList;
	return lwip_shutdown(pFiles[s].lwipSock, how);
}
int SysSocket(int domain, int type, int protocol){
	uint32_t i;
	LockCurrentFileList();
	PFile pFiles=GetTaskInfo(-1)->fileList;
	for (i = 0; i < FILE_MAX_NUM; i++) {
		if (pFiles[i].isUsed==FALSE) {
			break;
		}
	}
	
	int32_t sockInx= lwip_socket(domain,type,protocol);
	if(sockInx<0){
		return -1;
	}
	
	pFiles[i].lwipSock=sockInx;
	pFiles[i].fileType=1;
	pFiles[i].isUsed=TRUE;
	pFiles[i].pNetOper=&netOper;
	UnlockCurrentFileList();
	return i;
}
int SysConnect(int s, const struct sockaddr *name, socklen_t namelen){
	PFile pFiles=GetTaskInfo(-1)->fileList;
	return lwip_connect(pFiles[s].lwipSock,name,namelen);
}
int SysListen(int s, int backlog){
	PFile pFiles=GetTaskInfo(-1)->fileList;
	return lwip_listen(pFiles[s].lwipSock,backlog);
}
